from turtle import *
from random import *
from pathfinding import GameGraph, pathfinding

def square(x, y, size, sq_color):
    '''绘制小正方形, 代表一格'''

    # 将画笔移动到目标位置
    penup()
    goto(x, y)
    color(sq_color)
    pendown()

    # 画小正方形，并填充颜色
    begin_fill()
    for i in range(4):
        forward(size) # 向前size个单位长度
        left(90)
    end_fill()

def frame():
    '''绘制边框'''
    for i in range(-210, 200, 10):
        square(i, -200, 10, 'gray')
        square(i, 200, 10, 'gray')
    for i in range(-200, 200, 10):
        square(-210, i, 10, 'gray')
        square(190, i, 10, 'gray')

def change(direction):
    '''改变蛇的运动方向'''
    global aim_x, aim_y
    x, y = direction

    if aim_x != -x or aim_y != -y:
        aim_x = x
        aim_y = y

def inside(head_x, head_y):
    '''判断蛇是否在边框内'''
    if -210 < head_x < 190 and -200 < head_y < 200:
        return True
    else:
        return False

# 食物出现的所有可能位置
all_food = []
for x in range(-200, 190, 10):
    for y in range(-190, 200, 10):
        all_food.append((x, y))

def new_food():
    '''随机生成食物位置'''
    # 食物可能出现的位置（去掉蛇所在的位置）
    food = all_food.copy()
    for i in set(snake):
        food.remove(i)

    # 随机生成食物位置
    new_food_x, new_food_y = food.pop(randint(0, len(food) - 1))
    return new_food_x, new_food_y

# 蛇的起始位置
snake = [(0, 0)]

# 食物的位置
food_x, food_y = new_food()

# 蛇的起始方向 -- 用位移向量表示
aim_x, aim_y = 0, 0

def move():
    """移动"""
    # 获取食物位置
    global food_x, food_y, snake

    # 获取图片画面
    game_graph = GameGraph(snake.copy(), (food_x, food_y), {'xmin': -200, 'xmax': 180, 'ymin': -190, 'ymax': 190})

    # 更新下一步的前进方向
    aim_x, aim_y = pathfinding(game_graph)

    print('aim_x:', aim_x)
    print('aim_y:', aim_y)
    print('snake:', snake)
    # 蛇头进行移动
    head_move_x = snake[-1][0] + aim_x
    head_move_y = snake[-1][1] + aim_y

    # 如果撞到边框或者撞到自己
    if not inside(head_move_x, head_move_y) or (head_move_x, head_move_y) in snake:
        # 绘制蛇头（红色）
        square(head_move_x, head_move_y, 10, 'red')

        # 更新画面
        update()
        print('得分: ', len(snake))
        return

    # 如果未发生碰撞，蛇头移动完成
    snake.append((head_move_x, head_move_y))

    # 如果蛇吃到食物
    if head_move_x == food_x and head_move_y == food_y:
        # 如果蛇跑满屏幕，则胜利
        if(len(snake) == len(all_food)):
            print('YOU WIN!')
            return

        # 否则，刷新食物位置
        else:
            food_x, food_y = new_food()

            # 更新画面中的食物信息
            game_graph.set_food((food_x, food_y))

    # 如果移动之后，没有吃到食物，蛇尾移动
    else:
        snake.pop(0)

    # 清空窗口
    clear()

    # 绘制边框
    frame()

    # 绘制蛇身
    for body in snake:
        square(body[0], body[1], 10, 'black')

    # 绘制食物
    square(food_x, food_y, 10, 'green')

    # 更新窗口
    update()

    # 每隔一段时间，调用move()函数
    ontimer(move)

# 设置窗口大小
setup(420, 420)

# 设置窗口标题
title('贪吃蛇')

# 隐藏海龟
hideturtle()

# 关闭轨迹
tracer(False)



# 移动
move()

# 画面暂停
done()